package com.dc.datacollect.components.timer;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.SimpleFormatter;

/**
 * 定时执行器-添加/移除
 *
 * @author zhuangjie
 * @date 2023/06/24
 */

@Component
@Slf4j
public class TimerManager {
    @Data
    private static class TimerNode<T> {
        private Long timestamp;
        private ScheduledFuture<T> scheduledFuture;

        public TimerNode(Long timestamp,ScheduledFuture<T> scheduledFuture) {
            this.timestamp = timestamp;
            this.scheduledFuture = scheduledFuture;
        }
    }
    @Autowired
    private ScheduledExecutorService executor;
    private Map<String, TimerNode<?>> tasks = new HashMap<>();

    public synchronized void addTimer(String id, Runnable task, Long executeTime) {
        boolean isInvalid = (id == null || executeTime == null);
        TimerNode<?> timerNode = tasks.get(id);
        Boolean isExist = timerNode != null;
        if (isInvalid ) {
            return;
        }
        long currentTimeMillis = System.currentTimeMillis();
        long newTaskTimestamp = executeTime;
        if (isExist && timerNode.getTimestamp() != newTaskTimestamp && newTaskTimestamp > currentTimeMillis   ) {
            // 过期时间已经改变了
            ScheduledFuture<?> scheduledFuture = timerNode.getScheduledFuture();
            scheduledFuture.cancel(true);
            tasks.remove(task);
        }else if ( isExist ){
            return;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (isExist) {
            log.info("更新定时任务,id={}，触发时间：{}",id,format.format(new Date(executeTime)));
        }else {
            log.info("新增定时任务,id={}，触发时间：{}",id,format.format(new Date(executeTime)));
        }
        long delay = executeTime - System.currentTimeMillis();
        ScheduledFuture<?> scheduledFuture = executor.schedule(task, delay, TimeUnit.MILLISECONDS);
        tasks.put(id, new TimerNode<>(executeTime,scheduledFuture));
        log.info("当前定时任务数为{}个",tasks.size());

    }

    public void removeTimer(String id) {
        TimerNode<?> timerNode = tasks.get(id);
        if (timerNode != null && timerNode.getScheduledFuture() != null) {
            timerNode.getScheduledFuture().cancel(true);
            tasks.remove(id);
        }
    }
}
